package com.qsw.paper.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qsw.paper.constant.MessageConstants;
import com.qsw.paper.exception.ObjectException;
import com.qsw.paper.mapper.AdvisorsMapper;
import com.qsw.paper.mapper.ClassesMapper;
import com.qsw.paper.pojo.dto.CollegeDto;
import com.qsw.paper.pojo.dto.CollegeQueryDto;
import com.qsw.paper.pojo.entity.Advisors;
import com.qsw.paper.pojo.entity.Classes;
import com.qsw.paper.pojo.entity.Colleges;
import com.qsw.paper.mapper.CollegesMapper;
import com.qsw.paper.pojo.vo.CollegeStudentAndAdvisorCountVO;
import com.qsw.paper.pojo.vo.CollegeThesisPassRateVO;
import com.qsw.paper.result.PageResult;
import com.qsw.paper.service.ICollegesService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author qsw
 * @since 2024-11-15
 */
@Service
@RequiredArgsConstructor
public class CollegesServiceImpl extends ServiceImpl<CollegesMapper, Colleges> implements ICollegesService {

    private final ClassesMapper classesMapper;
    private final AdvisorsMapper advisorsMapper;

    /**
     * 添加学院
     *
     * @param collegeDto dto
     */
    @Override
    public void save(CollegeDto collegeDto) {
        //插入数据
        save(BeanUtil.copyProperties(collegeDto, Colleges.class).setCreatedAt(LocalDateTime.now()).setUpdatedAt(LocalDateTime.now()));
    }

    /**
     * 修改学院信息
     *
     * @param collegeDto dto
     */
    @Override
    public void update(CollegeDto collegeDto) {
        //修改数据
        updateById(BeanUtil.copyProperties(collegeDto, Colleges.class).setUpdatedAt(LocalDateTime.now()));
    }

    /**
     * 删除学院
     *
     * @param id 学院id
     */
    @Override
    public void deleteById(Integer id) {
        // 通过学院ID获取学院对象
        Colleges colleges = getById(id);
        // 如果学院不存在，抛出异常
        if (colleges == null) {
            throw new ObjectException(MessageConstants.COLLEGE_NOT_EXIST);
        }

        // 检查该学院是否有班级关联
        if (classesMapper.selectCount(new LambdaQueryWrapper<Classes>().eq(Classes::getCollegeId, id)) > 0) {
            // 如果存在班级关联，抛出异常，不能删除学院
            throw new ObjectException(MessageConstants.COLLEGE_IN_CLASSES);
        }

        // 检查该学院是否有导师关联
        if (advisorsMapper.selectCount(new LambdaQueryWrapper<Advisors>().eq(Advisors::getCollegeId, id)) > 0) {
            // 如果存在导师关联，抛出异常，不能删除学院
            throw new ObjectException(MessageConstants.ADVISORS_IN_CLASSES);
        }
        // 如果没有任何关联，执行删除操作
        removeById(id);
    }

    /**
     * 获取学院列表
     *
     * @param queryDto dto
     * @return 分页后的学院列表
     */
    @Override
    public PageResult<?> pageList(@NotNull CollegeQueryDto queryDto) {
        String collegeName = queryDto.getCollegeName();
        String dean = queryDto.getDean();
        Page<Colleges> collegesPage = baseMapper.selectPage(new Page<>(queryDto.getPageNum(),
                queryDto.getPageSize()), new LambdaQueryWrapper<Colleges>()
                .like(!StringUtils.isBlank(collegeName), Colleges::getCollegeName, collegeName)
                .like(!StringUtils.isBlank(dean), Colleges::getDean, dean)
                .orderByDesc(Colleges::getCreatedAt));
        return new PageResult<>(collegesPage.getTotal(), collegesPage.getRecords());
    }


    /**
     * 前7个学院下的论文通过率（近三个月）
     *
     * @return 数据列表
     */
    @Override
    public List<CollegeThesisPassRateVO> getCollegeThesisPassRate() {
        return baseMapper.getCollegeThesisPassRate();
    }

    /**
     * 获取前7个学院下的所有学生人数以及导师数量
     *
     * @return 数据列表
     */
    @Override
    public List<CollegeStudentAndAdvisorCountVO> getCollegeStudentAndAdvisorCount() {
        return baseMapper.getCollegeStudentAndAdvisorCount();
    }

}
